#ifndef __M_LOOPTHREAD_H__
#define __M_LOOPTHREAD_H__

#pragma once

#include "eventLoop.hpp"
#include <thread>
#include <mutex>
#include <condition_variable>

class LoopThread//将eventLoop和线程进行整合
{
private:
    EventLoop* _loop;
    std::thread _thread;
    std::mutex _mutex;
    std::condition_variable _cond;
    //如果实例化EventLoop对象再创建线程 将loop对象的线程id与创建的线程id绑定 那么在loop对象构造完成后到替换线程id期间 主线程的所有操作都视作在loop对象中执行

private:
    //1.在当前线程内创建EventLoop对象 2.唤醒在cond上等待的线程(主线程) 3.loop对象启动事件监控
    void threadEntry()
    {
        EventLoop loop;//loop对象的生命周期随线程的生命周期
        {
            std::unique_lock<std::mutex> lock(_mutex);//TODO 这里为什么要加锁
            _loop = &loop;
            _cond.notify_all();//loop对象实例化后 唤醒在cond上等待的线程
        }
        loop.start();
    }

public:
    LoopThread()
    : _loop(nullptr),
      _thread(std::bind(&LoopThread::threadEntry, this))
    {}

    //在获取线程对应的loop指针时 如果loop对象还未实例化 就应该阻塞等待实例化后再返回对象指针
    EventLoop* getLoop()
    {
        EventLoop* loop = nullptr;
        {
            std::unique_lock<std::mutex> lock(_mutex);
            _cond.wait(lock, [&](){ return _loop != nullptr; });//lamda表达式条件为假则阻塞等待
            loop = _loop;
        }
        return loop;
    }
};

#endif
